package com.wsc.personalblog.service.impl;

import com.wsc.personalblog.DTO.CommentDTO;
import com.wsc.personalblog.DTO.LeaveAMsgDTO;
import com.wsc.personalblog.DTO.LikeInfoDTO;
import com.wsc.personalblog.common.Constant;
import com.wsc.personalblog.entity.Comment;
import com.wsc.personalblog.entity.CommentExample;
import com.wsc.personalblog.mapper.CommentMapper;
import com.wsc.personalblog.service.CommentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class CommentServiceImpl implements CommentService {

    @Autowired
    private CommentMapper commentMapper;
    @Autowired
    private LikeServiceImpl likeService;
    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public Integer pubComment(Comment comment) {
        String photoFile = comment.getPhotoFile();
        if(photoFile != null && photoFile.trim().length() == 0) comment.setPhotoFile(null);
        comment.setPubDate(LocalDateTime.now());
        commentMapper.insertSelective(comment);
        System.out.println(comment.getId());
        // 清空redis中缓存的评论id集合，
        redisTemplate.delete(Constant.COMMENT_ID_SET);
        return comment.getId();
    }

    @Override
    public List<CommentDTO> getAllComment(Integer pageNum ,Integer articleId , Integer userId) {
        List<CommentDTO> commentDTOs = commentMapper.getAllComment(articleId);
        if(commentDTOs == null || commentDTOs.size() == 0) {
            return null;
        }
        // 组合模型组成树型结构
        List<CommentDTO> tree = tree(commentDTOs,userId);
        tree = tree.stream().peek((item)-> {
            recursionCount(item,item);
        }).collect(Collectors.toList());
        List<CommentDTO> result = null;
        for (CommentDTO item: tree) {
            result = new ArrayList();
            recursionRegroup(item,result);
            item.setChildren(result);
        }
        return tree;
    }
    // 递归计算子留言数
    private void recursionCount(CommentDTO l1 , CommentDTO l2){
        if(l1.getChildren().size() == 0) return;
        for (CommentDTO obj :l1.getChildren()) {
            l2.setMsgCount(l2.getMsgCount()+1);
            recursionCount(obj,l2);
        }
    }
    // 递归重组
    private void recursionRegroup(CommentDTO l, List<CommentDTO> result){
        if(l.getChildren().size() == 0) return;
        List<CommentDTO> children = l.getChildren();
        for (CommentDTO obj :children) {
            // 生成线性结构
            result.add(obj);
            recursionRegroup(obj,result);
            // 解除父子关系
            obj.setChildren(null);
        }
    }

    @Override
    public void removeCommentByIds(List<Integer> commentIds) {
        CommentExample commentExample = new CommentExample();
        CommentExample.Criteria criteria = commentExample.createCriteria();
        criteria.andIdIn(commentIds);
        commentMapper.deleteByExample(commentExample);
    }

    private List<CommentDTO> tree(List<CommentDTO> commentDTOs,Integer userId){
        List<CommentDTO> res = new ArrayList<>();
        HashMap<Integer, CommentDTO> hm = new HashMap<>();
        for (CommentDTO commentDTO:  commentDTOs) {
            Integer id = commentDTO.getId();
            LikeInfoDTO commentLikeNumAndLikeStatus = likeService.getCommentLikeNumAndLikeStatus(id, userId);
            commentDTO.setLikeInfoDTO(commentLikeNumAndLikeStatus);
            hm.put(commentDTO.getId(),commentDTO);
        }
        for (CommentDTO commentDTO:  commentDTOs) {
            Integer superId = commentDTO.getSuperId();
            // 如果没有父节点就添加父节点
            if(superId == null) {
                res.add(commentDTO);
                continue;
            }
            // 如果有父节点就加入到父节点
            CommentDTO pCommentDTO1 = hm.get(superId);
            pCommentDTO1.getChildren().add(commentDTO);
        }
        return res;

    }
}
